package com.mew.lobby.net;

import com.mew.lobby.annotation.LobbyHandler;
import com.mew.common.config.SpringContextBean;
import com.zebra.common.ZebraException;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.stereotype.Component;

import java.util.Optional;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;


@Component
public class InitializeHandlerMapping {

    private final static ConcurrentHashMap<Integer, MewHandler> handlerMapping = new ConcurrentHashMap<>();

    public static MewHandler getMapping(Integer cmd) throws ZebraException {
        return handlerMapping.get(cmd);
    }


    public static void initializeMapping()throws Exception{
        ClassPathScanningCandidateComponentProvider provider = new ClassPathScanningCandidateComponentProvider(false);
        provider.addIncludeFilter(new AnnotationTypeFilter(LobbyHandler.class));
        Set<BeanDefinition> components = provider.findCandidateComponents("com/mew/lobby/handler");
         for (BeanDefinition component : components) {
             Class clazz =  Class.forName(component.getBeanClassName());
             if(clazz.isAnnotationPresent(LobbyHandler.class)){
                 LobbyHandler lobbyHandler = (LobbyHandler) clazz.getAnnotation(LobbyHandler.class);
                 putMapping(lobbyHandler.value().cmd(), clazz);
             }
         }
    }

    private static void putMapping(int cmd, Class<MewHandler> clazz)throws  Exception{
        if (null == clazz ||cmd == 0){
            throw new Exception("build Handler exception");
        }
        handlerMapping.put(cmd, Optional.ofNullable(SpringContextBean.getBean(clazz)).orElseThrow(()-> new Exception("build handlerMapping,no exception")));
    }



}
